package com.xtx.air.bo.flight.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import com.xtx.exception.BOException;
import com.xtx.util.RegularUtil;
import com.xtx.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.xtx.air.bo.flight.IFlightBO;
import com.xtx.air.common.XtxCollectionUtils;
import com.xtx.air.common.XtxDateUtils;
import com.xtx.air.dao.flight.IFlightDAO;
import com.xtx.air.dao.flight.IFlightStorageDAO;
import com.xtx.air.dataobject.FlightDO;
import com.xtx.air.dataobject.FlightStorageDO;

public class FlightBOImpl implements IFlightBO {
	private Log logger = LogFactory.getLog(this.getClass());
	private IFlightDAO flightDAO;
	private IFlightStorageDAO flightStorageDAO;

	public void setFlightStorageDAO(IFlightStorageDAO flightStorageDAO) {
		this.flightStorageDAO = flightStorageDAO;
	}

	public void setFlightDAO(IFlightDAO flightDAO) {
		this.flightDAO = flightDAO;
	}

    @Override
    public boolean addFlight(FlightDO flightDO) {
        validateFlight(flightDO);
        try {
            flightDAO.addFlight(flightDO);
            return true;
        } catch (Exception e) {
            logger.error("航班信息添加失败", e);
            return false;
        }
    }

    @Override
    public boolean updateFlight(FlightDO flightDO) {
        validateFlight(flightDO);
        validateUpdateFlight(flightDO);
        try {
            flightDAO.updateFlight(flightDO);
            return true;
        } catch (Exception e) {
            logger.error("航班信息更新失败", e);
            return false;
        }
    }

    @Override
    public void addFlightAndStorage(FlightDO flightDO, List<FlightStorageDO> storageDOList) {
        boolean isSuccess = false;
        isSuccess = addFlight(flightDO);
        if (!isSuccess) {
            throw new BOException("添加航班信息失败");
        }
        for (FlightStorageDO flightStorageDO : storageDOList) {
            isSuccess = addFlightStorage(flightStorageDO);
            if (!isSuccess) {
                throw new BOException("添加库存信息失败");
            }
        }
    }

    @Override
    public void updateStorageByFid(Long fid, List<FlightStorageDO> storageDOList) {
        try {
            flightStorageDAO.deleteStorageByFid(fid);
            addFlightStorage(storageDOList);
        } catch (Exception e) {
            logger.error("修改库存失败", e);
            throw new BOException("修改库存失败");
        }
    }

    private void validateFlight(FlightDO flightDO) {
        if (flightDO == null) {
            throw new IllegalArgumentException("航班信息不能为空");
        } else if (StringUtil.isEmpty(flightDO.getFlight_company())) {
            throw new IllegalArgumentException("航空公司不能为空");
        } else if (StringUtil.isEmpty(flightDO.getFlight_num())) {
            throw new IllegalArgumentException("航班号不能为空");
        } else if (StringUtil.isEmpty(flightDO.getStart_city())) {
            throw new IllegalArgumentException("出发城市不能为空");
        } else if (StringUtil.isEmpty(flightDO.getStart_airport())) {
            throw new IllegalArgumentException("出发机场不能为空");
        } else if (StringUtil.isEmpty(flightDO.getStart_terminal())) {
            throw new IllegalArgumentException("出发航站楼不能为空");
        } else if (StringUtil.isEmpty(flightDO.getStart_time())) {
            throw new IllegalArgumentException("出发时间不能为空");
        } else if (StringUtil.isEmpty(flightDO.getEnd_city())) {
            throw new IllegalArgumentException("到达城市不能为空");
        } else if (StringUtil.isEmpty(flightDO.getEnd_airport())) {
            throw new IllegalArgumentException("到达机场不能为空");
        } else if (StringUtil.isEmpty(flightDO.getEnd_terminal())) {
            throw new IllegalArgumentException("到达航站楼不能为空");
        } else if (StringUtil.isEmpty(flightDO.getEnd_time())) {
            throw new IllegalArgumentException("到达时间不能为空");
        } else if (StringUtil.isEmpty(flightDO.getStandard_fee())) {
            throw new IllegalArgumentException("标准费用不能为空");
        } else if (StringUtil.isEmpty(flightDO.getBuild_fee())) {
            throw new IllegalArgumentException("机场建设费不能为空");
        } else if (StringUtil.isEmpty(flightDO.getFuel_fee())) {
            throw new IllegalArgumentException("燃油附加费不能为空");
        }else if (flightDO.getCreator_id() == null) {
            throw new IllegalArgumentException("创建人员不能为空");
        }
    }

    private void validateUpdateFlight(FlightDO flightDO) {
        if (flightDO.getFid() == null) {
            throw new IllegalArgumentException("航班ID不能为空");
        }
    }

	@Override
	public List<FlightDO> findFlight(FlightDO flightDO) {
		try {
			if (flightDO == null) {
				flightDO = new FlightDO();
			}
			return flightDAO.findFlight(flightDO);
		} catch (Exception e) {
			logger.error("航班信息查询失败", e);
			return Collections.emptyList();
		}
	}

	@Override
	public boolean addFlightStorage(FlightStorageDO flightStorageDO) {
        validateFlightStorage(flightStorageDO);
		try {
			flightStorageDAO.addStorage(flightStorageDO);
			return true;
		} catch (Exception e) {
			logger.error("航班库存信息添加失败", e);
			return false;
		}
	}

    @Override
    public void addFlightStorage(List<FlightStorageDO> flightStorageList) {
        for (FlightStorageDO storageDO : flightStorageList) {
            if (!addFlightStorage(storageDO)) {
                throw new BOException("添加库存信息失败");
            }
        }
    }

    private void validateFlightStorage(FlightStorageDO flightStorageDO) {
        if (flightStorageDO == null) {
            throw new IllegalArgumentException("库存信息不能为空");
        } else if (StringUtil.isEmpty(flightStorageDO.getBoarding_date())) {
            throw new IllegalArgumentException("登机时间不能为空");
        } else if (StringUtil.isEmpty(flightStorageDO.getClass_type())) {
            throw new IllegalArgumentException("舱位不能为空");
        } else if (flightStorageDO.getCurrent_count() < 0) {
            throw new IllegalArgumentException("库存必须大于等于0");
        } else if (!Pattern.matches(RegularUtil.REG_AMOUNT, flightStorageDO.getDiscount())) {
            throw new IllegalArgumentException("折扣必须为正数，且精确到两位小数");
        } else if (!Pattern.matches(RegularUtil.REG_AMOUNT, flightStorageDO.getSpec_discount())) {
            throw new IllegalArgumentException("特殊折扣必须为正数，且精确到两位小数");
        } else if (flightStorageDO.getCreator_id() == null) {
            throw new IllegalArgumentException("创建人员不能为空");
        }
    }

	@Override
	public boolean updateFlightStorage(FlightStorageDO flightStorageDO) {
		if (flightStorageDO == null) {
			throw new IllegalArgumentException("航班库存信息为空，更新失败");
		} else if (flightStorageDO.getSid() == null) {
			throw new IllegalArgumentException("航班库存ID为空，更新失败");
		}
		try {
			flightStorageDAO.updateStorage(flightStorageDO);
			return true;
		} catch (Exception e) {
			logger.error("航班库存信息更新失败", e);
			return false;
		}
	}

	@Override
	public List<FlightStorageDO> findFlightStorage(Long flightId) {
		return findFlightStorage(flightId, null);
	}

	@Override
	public List<FlightStorageDO> findFlightStorage(Long flightId, String boarding_date) {
		if (flightId == null) {
			throw new IllegalArgumentException("航班ID为空，查询库存失败");
		} else if (StringUtils.isNotBlank(boarding_date) && !XtxDateUtils.checkBoardDate(boarding_date)) {
			throw new IllegalArgumentException("登机日期不正确，查询库存失败");
		}
		try {
			FlightStorageDO flightStorageDO = new FlightStorageDO();
			flightStorageDO.setFid(flightId);
			flightStorageDO.setBoarding_date(boarding_date);
			return flightStorageDAO.findStorage(flightStorageDO);
		} catch (Exception e) {
			logger.error("航班库存信息查询失败", e);
			return Collections.emptyList();
		}
	}

	@Override
	public Map<String, List<FlightDO>> findFlightStorage(String start_city, String end_city, String start_date,
			String end_date) {
		Map<String, List<FlightDO>> result = new HashMap<String, List<FlightDO>>();
		try {
			FlightDO flightDO = new FlightDO();
			flightDO.setStart_city(start_city);
			flightDO.setEnd_city(end_city);
			List<FlightDO> flights = findFlight(flightDO);
			String date = start_date;
			for (; !date.equals(end_date); date = XtxDateUtils.nextBoardDate(date)) {
				List<FlightDO> flightsToUse = new ArrayList<FlightDO>();
				for (FlightDO flight : flights) {
					flightsToUse.add(getFlight(flight.getFid(), date));
				}
				result.put(date, flightsToUse);
			}
		} catch (Exception e) {
			logger.error("航班库存信息查询失败", e);
		}
		return result;
	}

    @Override
    public List<FlightDO> findFlightByStorageCreator(FlightStorageDO flightStorageDO) {
        try {
            return flightStorageDAO.findFlightIdByStorageCreator(flightStorageDO);
        } catch (Exception e) {
            logger.error("查询创建者对应的航班失败", e);
            return Collections.EMPTY_LIST;
        }
    }

    @Override
	public FlightDO getFlight(Long flightId, String boarding_date) {
		FlightDO flightDO = new FlightDO();
		flightDO.setFid(flightId);
		flightDO = XtxCollectionUtils.returnOnlyOne(findFlight(flightDO));
		if (flightDO != null) {
			flightDO.setStorages(findFlightStorage(flightDO.getFid(), boarding_date));
		}
		return flightDO;
	}

    @Override
    public FlightDO getFlight(String num, String startCity, String endCity) {
        FlightDO flightDO = new FlightDO();
		flightDO.setFlight_num(num);
        flightDO.setStart_city(startCity);
        flightDO.setEnd_city(endCity);
        flightDO = XtxCollectionUtils.returnOnlyOne(findFlight(flightDO));
        return flightDO;
    }

}